﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace ImageRenderControl
{
    public class ArcShape : Shape
    {
        public PointF StartPoint { get; set; }
        public PointF MiddlePoint { get; set; }
        public PointF EndPoint { get; set; }

        // 添加图像坐标属性
        public PointF StartPointImage { get; private set; }
        public PointF MiddlePointImage { get; private set; }
        public PointF EndPointImage { get; private set; }

        public float TopLeftX { get; set; }
        public float TopLeftY { get; set; }
        public float Width { get; set; }
        public float Height { get; set; }
        public float StartAngle { get; set; }
        public float SweepAngle { get; set; }
        public Pen Pen { get; set; }
        public float Rotation { get; private set; } = 0f;

        public const float RotationDelta = 1f;
        private const float HANDLE_SIZE = 8f;
        private const float MIN_SIZE = 10f;

        // 缓存原始旋转中心点
        private PointF _rotationCenter;

        // 计算属性获取椭圆中心
        public float CenterX => TopLeftX + Width / 2;
        public float CenterY => TopLeftY + Height / 2;


        // 缓存变换矩阵
        private bool _matrixDirty = true;
        private Matrix _rotationMatrix;
        public Matrix RotationMatrix
        {
            get
            {
                if (_matrixDirty || _rotationMatrix == null)
                {
                    _rotationMatrix?.Dispose();
                    _rotationMatrix = new Matrix();

                    // 安全检查：确保宽高不为零，避免除零错误
                    if (Width > 0 && Height > 0)
                    {
                        try
                        {
                            PointF pivot = GetArcPoint(StartAngle); // 以起始点作为旋转中心
                            _rotationMatrix.Translate(pivot.X, pivot.Y);
                            _rotationMatrix.Rotate(Rotation);
                            _rotationMatrix.Translate(-pivot.X, -pivot.Y);
                        }
                        catch (Exception)
                        {
                            // 如果计算过程出错，使用默认中心点
                            float centerX = TopLeftX + Width / 2;
                            float centerY = TopLeftY + Height / 2;
                            _rotationMatrix.RotateAt(Rotation, new PointF(centerX, centerY));
                        }
                    }
                    else
                    {
                        // 如果宽高为零，使用无旋转的矩阵
                        _rotationMatrix.Reset();
                    }

                    _matrixDirty = false;
                }
                return _rotationMatrix;
            }
        }

        // 三点构造函数 - 仅使用Overlay坐标
        public ArcShape(PointF startPoint, PointF middlePoint, PointF endPoint, Pen pen = null)
        {
            try
            {
                if (!FindCircle(startPoint, middlePoint, endPoint, out PointF center, out float radius))
                {
                    throw new ArgumentException("Points are colinear or too close together");
                }

                // 设置椭圆基本参数
                TopLeftX = center.X - radius;
                TopLeftY = center.Y - radius;
                Width = 2 * radius;
                Height = 2 * radius;

                // 计算三点相对于中心的角度
                float startAngle = GetAngle(center, startPoint);
                float middleAngle = GetAngle(center, middlePoint);
                float endAngle = GetAngle(center, endPoint);

                // 确定圆弧的起始角度和扫描角度
                StartAngle = startAngle; // 第一个点作为起始角度

                // 确定扫描方向（顺时针或逆时针）
                if (IsAngleInSweep(middleAngle, startAngle, endAngle, true))
                {
                    // 顺时针方向
                    SweepAngle = (endAngle - startAngle + 360) % 360;
                    if (SweepAngle == 0) SweepAngle = 360; // 整圆情况
                }
                else
                {
                    // 逆时针方向
                    SweepAngle = -((startAngle - endAngle + 360) % 360);
                    if (SweepAngle == 0) SweepAngle = -360; // 整圆情况
                }

                // 初始化旋转中心为起始点
                _rotationCenter = startPoint;

                // 重要：更新控制点，使它们精确匹配标准圆弧上的点
                UpdateArcPoints();

                // 保存原始的图像坐标点
                StartPointImage = startPoint;
                MiddlePointImage = middlePoint;
                EndPointImage = endPoint;
            }
            catch (Exception)
            {
                // 出现异常时，创建一个默认小圆弧
                TopLeftX = (startPoint.X + middlePoint.X + endPoint.X) / 3 - 50;
                TopLeftY = (startPoint.Y + middlePoint.Y + endPoint.Y) / 3 - 50;
                Width = 100;
                Height = 100;
                StartAngle = 0;
                SweepAngle = 90;

                // 初始化旋转中心为默认位置
                _rotationCenter = new PointF(TopLeftX + Width, TopLeftY + Height / 2);

                // 设置默认控制点
                UpdateArcPoints();

                // 保存原始的图像坐标点
                StartPointImage = startPoint;
                MiddlePointImage = middlePoint;
                EndPointImage = endPoint;
            }

            Pen = pen ?? new Pen(Color.Red, 2);
        }

        // 三点构造函数 - 同时使用Overlay坐标和图像坐标
        public ArcShape(PointF startPoint, PointF middlePoint, PointF endPoint,
                       PointF startPointImage, PointF middlePointImage, PointF endPointImage,
                       Pen pen = null)
        {
            try
            {
                if (!FindCircle(startPoint, middlePoint, endPoint, out PointF center, out float radius))
                {
                    throw new ArgumentException("Points are colinear or too close together");
                }

                // 设置椭圆基本参数
                TopLeftX = center.X - radius;
                TopLeftY = center.Y - radius;
                Width = 2 * radius;
                Height = 2 * radius;

                // 计算三点相对于中心的角度
                float startAngle = GetAngle(center, startPoint);
                float middleAngle = GetAngle(center, middlePoint);
                float endAngle = GetAngle(center, endPoint);

                // 确定圆弧的起始角度和扫描角度
                StartAngle = startAngle; // 第一个点作为起始角度

                // 确定扫描方向（顺时针或逆时针）
                if (IsAngleInSweep(middleAngle, startAngle, endAngle, true))
                {
                    // 顺时针方向
                    SweepAngle = (endAngle - startAngle + 360) % 360;
                    if (SweepAngle == 0) SweepAngle = 360; // 整圆情况
                }
                else
                {
                    // 逆时针方向
                    SweepAngle = -((startAngle - endAngle + 360) % 360);
                    if (SweepAngle == 0) SweepAngle = -360; // 整圆情况
                }

                // 初始化旋转中心为起始点
                _rotationCenter = startPoint;

                // 重要：更新控制点，使它们精确匹配标准圆弧上的点
                UpdateArcPoints();

                // 设置图像坐标
                StartPointImage = startPointImage;
                MiddlePointImage = middlePointImage;
                EndPointImage = endPointImage;

            }
            catch (Exception)
            {
                // 出现异常时，创建一个默认小圆弧
                TopLeftX = (startPoint.X + middlePoint.X + endPoint.X) / 3 - 50;
                TopLeftY = (startPoint.Y + middlePoint.Y + endPoint.Y) / 3 - 50;
                Width = 100;
                Height = 100;
                StartAngle = 0;
                SweepAngle = 90;

                // 初始化旋转中心为默认位置
                _rotationCenter = new PointF(TopLeftX + Width, TopLeftY + Height / 2);

                // 设置默认控制点和更新控制点位置
                UpdateArcPoints();

                // 设置图像坐标
                StartPointImage = startPointImage;
                MiddlePointImage = middlePointImage;
                EndPointImage = endPointImage;
            }

            Pen = pen ?? new Pen(Color.Red, 2);
        }

        // 更新三点位置到标准圆弧上的点
        private void UpdateArcPoints()
        {
            // 计算圆心
            float centerX = TopLeftX + Width / 2;
            float centerY = TopLeftY + Height / 2;

            // 计算半径
            float radiusX = Width / 2;
            float radiusY = Height / 2;

            // 计算起始点、中间点和终点坐标
            float startAngleRad = StartAngle * (float)Math.PI / 180;
            PointF newStartPoint = new PointF(
                centerX + radiusX * (float)Math.Cos(startAngleRad),
                centerY + radiusY * (float)Math.Sin(startAngleRad)
            );

            // 中间点在圆弧的中间位置
            float middleAngleRad = (StartAngle + SweepAngle / 2) * (float)Math.PI / 180;
            PointF newMiddlePoint = new PointF(
                centerX + radiusX * (float)Math.Cos(middleAngleRad),
                centerY + radiusY * (float)Math.Sin(middleAngleRad)
            );

            // 终点位置
            float endAngleRad = (StartAngle + SweepAngle) * (float)Math.PI / 180;
            PointF newEndPoint = new PointF(
                centerX + radiusX * (float)Math.Cos(endAngleRad),
                centerY + radiusY * (float)Math.Sin(endAngleRad)
            );

            // 如果这是首次更新点（构造函数中），保存旋转中心（起始点）
            if (_rotationCenter == PointF.Empty)
            {
                _rotationCenter = newStartPoint;
            }

            // 如果有旋转，应用旋转变换
            if (Rotation != 0)
            {
                // 创建临时矩阵用于变换点
                using (Matrix tempMatrix = new Matrix())
                {
                    // 构建适当的旋转变换
                    tempMatrix.Translate(_rotationCenter.X, _rotationCenter.Y);
                    tempMatrix.Rotate(Rotation);
                    tempMatrix.Translate(-_rotationCenter.X, -_rotationCenter.Y);

                    // 变换三个控制点
                    PointF[] points = new PointF[] { newStartPoint, newMiddlePoint, newEndPoint };
                    tempMatrix.TransformPoints(points);

                    // 更新控制点
                    StartPoint = points[0];
                    MiddlePoint = points[1];
                    EndPoint = points[2];
                }
            }
            else
            {
                // 无旋转，直接更新
                StartPoint = newStartPoint;
                MiddlePoint = newMiddlePoint;
                EndPoint = newEndPoint;
            }
        }


        // 更新三点位置的方法，同时更新图像坐标
        public void UpdatePoints(PointF newStartPoint, PointF newMiddlePoint, PointF newEndPoint, Func<PointF, PointF> overlayToImageTransform = null)
        {
            try
            {
                if (!FindCircle(newStartPoint, newMiddlePoint, newEndPoint, out PointF center, out float radius))
                {
                    throw new ArgumentException("Points are colinear or too close together");
                }

                // 更新椭圆基本参数
                TopLeftX = center.X - radius;
                TopLeftY = center.Y - radius;
                Width = 2 * radius;
                Height = 2 * radius;

                // 重新计算三点相对于中心的角度
                float startAngle = GetAngle(center, newStartPoint);
                float middleAngle = GetAngle(center, newMiddlePoint);
                float endAngle = GetAngle(center, newEndPoint);

                // 更新圆弧的起始角度和扫描角度
                StartAngle = startAngle;

                // 确定扫描方向
                if (IsAngleInSweep(middleAngle, startAngle, endAngle, true))
                {
                    SweepAngle = (endAngle - startAngle + 360) % 360;
                    if (SweepAngle == 0) SweepAngle = 360;
                }
                else
                {
                    SweepAngle = -((startAngle - endAngle + 360) % 360);
                    if (SweepAngle == 0) SweepAngle = -360;
                }

                // 更新旋转中心为新的起始点位置
                _rotationCenter = newStartPoint;

                // 标记矩阵为脏，需要重新计算
                _matrixDirty = true;

                // 更新控制点到标准圆弧上的点
                UpdateArcPoints();

                // 更新图像坐标
                if (overlayToImageTransform != null)
                {
                    UpdateImageCoordinates(overlayToImageTransform);
                }
            }
            catch
            {
                // 错误处理：维持当前状态或使用默认值
            }
        }


        // 获取图像坐标系中的所有关键点
        public PointF[] GetImageCoordinatePoints()
        {
            return new PointF[] { StartPointImage, MiddlePointImage, EndPointImage };
        }

        // 获取Overlay坐标系中的所有关键点
        public PointF[] GetOverlayCoordinatePoints()
        {
            return new PointF[] { StartPoint, MiddlePoint, EndPoint };
        }

        // 更新图像坐标
        public override void UpdateImageCoordinates(Func<PointF, PointF> overlayToImageTransform)
        {
            if (overlayToImageTransform == null) return;

            // 转换控制点坐标
            StartPointImage = overlayToImageTransform(StartPoint);
            MiddlePointImage = overlayToImageTransform(MiddlePoint);
            EndPointImage = overlayToImageTransform(EndPoint);
        }


        // 判断一个角度是否在两个角度形成的扫描区间内
        private bool IsAngleInSweep(float testAngle, float startAngle, float endAngle, bool clockwise)
        {
            // 将所有角度标准化到0-360
            testAngle = (testAngle + 360) % 360;
            startAngle = (startAngle + 360) % 360;
            endAngle = (endAngle + 360) % 360;

            if (clockwise)
            {
                if (startAngle <= endAngle)
                {
                    // 扫描不跨越0度
                    return testAngle >= startAngle && testAngle <= endAngle;
                }
                else
                {
                    // 扫描跨越0度
                    return testAngle >= startAngle || testAngle <= endAngle;
                }
            }
            else
            {
                if (startAngle >= endAngle)
                {
                    // 扫描不跨越0度
                    return testAngle <= startAngle && testAngle >= endAngle;
                }
                else
                {
                    // 扫描跨越0度
                    return testAngle <= startAngle || testAngle >= endAngle;
                }
            }
        }

        // 原始构造函数
        public ArcShape(float topLeftX, float topLeftY, float width, float height,
            float startAngle, float sweepAngle, Pen pen = null)
        {
            TopLeftX = topLeftX;
            TopLeftY = topLeftY;
            Width = width;
            Height = height;
            StartAngle = startAngle;
            SweepAngle = sweepAngle;
            Pen = pen ?? new Pen(Color.Red, 2);

            // 计算旋转中心（起始点）
            float centerX = topLeftX + width / 2;
            float centerY = topLeftY + height / 2;
            float radiusX = width / 2;
            float radiusY = height / 2;
            float startAngleRad = startAngle * (float)Math.PI / 180;
            _rotationCenter = new PointF(
                centerX + radiusX * (float)Math.Cos(startAngleRad),
                centerY + radiusY * (float)Math.Sin(startAngleRad)
            );

            // 初始化控制点
            UpdateArcPoints();

            // 初始化图像坐标为默认值
            StartPointImage = new PointF(0, 0);
            MiddlePointImage = new PointF(0, 0);
            EndPointImage = new PointF(0, 0);
        }

        // 计算三点确定的圆
        private bool FindCircle(PointF a, PointF b, PointF c, out PointF center, out float radius)
        {
            // 确保三点不共线且距离足够
            float epsilon = 0.001f;
            if (Math.Abs((b.Y - a.Y) * (c.X - b.X) - (c.Y - b.Y) * (b.X - a.X)) < epsilon)
            {
                center = PointF.Empty;
                radius = 0;
                return false;
            }

            // 计算中点
            PointF midAB = MidPoint(a, b);
            PointF midBC = MidPoint(b, c);

            // 计算斜率，需要进行除零检查
            float slopeAB = Math.Abs(b.X - a.X) < epsilon ? float.MaxValue : (b.Y - a.Y) / (b.X - a.X);
            float slopeBC = Math.Abs(c.X - b.X) < epsilon ? float.MaxValue : (c.Y - b.Y) / (c.X - b.X);

            // 计算垂直斜率，需要检查斜率是否为零
            float perpSlopeAB = Math.Abs(slopeAB) < epsilon ? 0 : -1 / slopeAB;
            float perpSlopeBC = Math.Abs(slopeBC) < epsilon ? 0 : -1 / slopeBC;

            // 特殊情况处理：垂直线
            if (Math.Abs(perpSlopeAB - perpSlopeBC) < epsilon)
            {
                center = PointF.Empty;
                radius = 0;
                return false;
            }

            // 解线性方程组求圆心
            float centerX, centerY;

            if (float.IsInfinity(perpSlopeAB))
            {
                // AB中垂线是水平的
                centerX = midAB.X;
                centerY = perpSlopeBC * (centerX - midBC.X) + midBC.Y;
            }
            else if (float.IsInfinity(perpSlopeBC))
            {
                // BC中垂线是水平的
                centerX = midBC.X;
                centerY = perpSlopeAB * (centerX - midAB.X) + midAB.Y;
            }
            else
            {
                // 正常情况下的计算
                centerX = (midBC.Y - midAB.Y + perpSlopeAB * midAB.X - perpSlopeBC * midBC.X) / (perpSlopeAB - perpSlopeBC);
                centerY = perpSlopeAB * (centerX - midAB.X) + midAB.Y;
            }

            center = new PointF(centerX, centerY);
            radius = Distance(center, a);
            return true;
        }

        // 计算角度参数
        private void CalculateAngles(PointF center, PointF start, PointF mid, PointF end)
        {
            float angleStart = GetAngle(center, start);
            float angleMid = GetAngle(center, mid);
            float angleEnd = GetAngle(center, end);

            // 确定扫掠方向
            if (!IsAngleBetween(angleMid, angleStart, angleEnd))
            {
                // 反向扫掠
                SweepAngle = -(360 - Math.Abs(angleEnd - angleStart)) % 360;
            }
            else
            {
                SweepAngle = (angleEnd - angleStart + 360) % 360;
            }
            StartAngle = angleStart;
        }

        #region 几何计算工具方法
        private PointF MidPoint(PointF a, PointF b) =>
            new PointF((a.X + b.X) / 2, (a.Y + b.Y) / 2);

        private float Distance(PointF a, PointF b) =>
            (float)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2));

        private float GetAngle(PointF center, PointF point)
        {
            float dx = point.X - center.X;
            float dy = point.Y - center.Y;
            return (float)(Math.Atan2(dy, dx) * 180 / Math.PI + 360) % 360;
        }

        private bool IsAngleBetween(float testAngle, float startAngle, float endAngle)
        {
            // 标准化角度到0-360度
            testAngle = (testAngle + 360) % 360;
            startAngle = (startAngle + 360) % 360;
            endAngle = (endAngle + 360) % 360;

            if (startAngle <= endAngle)
                return testAngle >= startAngle && testAngle <= endAngle;
            else
                return testAngle >= startAngle || testAngle <= endAngle;
        }
        #endregion

        #region 图形交互逻辑

        // 旋转方法，带图像坐标更新 
        public override void AdjustRotation(float angleDelta, Func<PointF, PointF> overlayToImageTransform)
        {
            Rotation = (Rotation + angleDelta) % 360;
            if (Rotation < 0) Rotation += 360;
            _matrixDirty = true;

            // 更新控制点位置
            UpdateArcPoints();

            // 如果有坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 调整大小方法，带图像坐标更新
        public override void AdjustSize(float factor, Func<PointF, PointF> overlayToImageTransform)
        {
            // 计算中心点
            float centerX = TopLeftX + Width / 2;
            float centerY = TopLeftY + Height / 2;

            // 新的宽高
            float newWidth = Width * factor;
            float newHeight = Height * factor;

            // 确保大小不小于最小值
            if (newWidth < MIN_SIZE || newHeight < MIN_SIZE) return;

            // 更新左上角位置和尺寸
            TopLeftX = centerX - newWidth / 2;
            TopLeftY = centerY - newHeight / 2;
            Width = newWidth;
            Height = newHeight;

            // 更新控制点位置
            UpdateArcPoints();

            _matrixDirty = true;

            // 如果有坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 更新控制点位置的方法，可选地更新图像坐标
        public void UpdateControlPoints(Func<PointF, PointF> overlayToImageTransform = null)
        {
            // 更新控制点到标准圆弧上的点
            UpdateArcPoints();

            // 如果提供了坐标转换函数，则更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 调整起始角度
        public void AdjustStartAngle(PointF mousePoint, Func<PointF, PointF> overlayToImageTransform = null)
        {
            // 将鼠标点转换为圆弧中心的相对坐标
            PointF center = new PointF(TopLeftX + Width / 2, TopLeftY + Height / 2);

            // 计算鼠标点相对于中心的角度
            float angle = (float)Math.Atan2(mousePoint.Y - center.Y, mousePoint.X - center.X) * 180 / (float)Math.PI;

            // 调整为0-360度范围
            if (angle < 0) angle += 360;

            // 保存当前终点角度
            float endAngle = (StartAngle + SweepAngle + 360) % 360;

            // 更新起始角度
            StartAngle = angle;

            // 更新扫描角度，保持终点位置不变
            if (SweepAngle >= 0) // 顺时针弧
            {
                SweepAngle = (endAngle - angle + 360) % 360;
                if (SweepAngle == 0) SweepAngle = 360; // 整圆情况
            }
            else // 逆时针弧
            {
                SweepAngle = -((angle - endAngle + 360) % 360);
                if (SweepAngle == 0) SweepAngle = -360; // 整圆情况
            }

            // 更新旋转中心为新的起始点位置
            float startAngleRad = StartAngle * (float)Math.PI / 180;
            _rotationCenter = new PointF(
                center.X + (Width / 2) * (float)Math.Cos(startAngleRad),
                center.Y + (Height / 2) * (float)Math.Sin(startAngleRad)
            );

            // 标记矩阵为脏
            _matrixDirty = true;

            // 更新控制点
            UpdateArcPoints();

            // 如果提供了坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 调整终止角度
        public void AdjustEndAngle(PointF mousePoint, Func<PointF, PointF> overlayToImageTransform = null)
        {
            // 将鼠标点转换为圆弧中心的相对坐标
            PointF center = new PointF(TopLeftX + Width / 2, TopLeftY + Height / 2);

            // 计算鼠标点相对于中心的角度
            float angle = (float)Math.Atan2(mousePoint.Y - center.Y, mousePoint.X - center.X) * 180 / (float)Math.PI;

            // 调整为0-360度范围
            if (angle < 0) angle += 360;

            // 计算新的扫描角度
            float sweepAngle;

            if (SweepAngle >= 0) // 保持顺时针方向
            {
                sweepAngle = (angle - StartAngle + 360) % 360;
                if (sweepAngle == 0) sweepAngle = 360; // 整圆情况
            }
            else // 保持逆时针方向
            {
                sweepAngle = -((StartAngle - angle + 360) % 360);
                if (sweepAngle == 0) sweepAngle = -360; // 整圆情况
            }

            // 更新扫描角度
            SweepAngle = sweepAngle;

            // 更新控制点
            UpdateArcPoints();

            // 如果提供了坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        // 更新圆弧的逻辑区域（用于拖拽调整尺寸时调用）
        public void UpdateFromResizing(float newX, float newY, float newWidth, float newHeight, Func<PointF, PointF> overlayToImageTransform = null)
        {
            // 确保大小不小于最小值
            if (newWidth < MIN_SIZE || newHeight < MIN_SIZE) return;

            TopLeftX = newX;
            TopLeftY = newY;
            Width = newWidth;
            Height = newHeight;

            _matrixDirty = true;

            // 更新控制点位置
            UpdateArcPoints();

            // 如果有坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        public override void Draw(Graphics g)
        {
            // 实现Draw方法
            if (Width <= 0 || Height <= 0) return;

            // 保存图形状态
            GraphicsState state = g.Save();

            try
            {
                g.MultiplyTransform(RotationMatrix);

                using (Pen drawPen = IsSelected ? new Pen(Color.Blue, Pen.Width) : (Pen)Pen.Clone())
                {
                    g.DrawArc(drawPen, TopLeftX, TopLeftY, Width, Height, StartAngle, SweepAngle);
                }

                // 如果选中，绘制控制点
                if (IsSelected)
                {
                    var handles = GetHandleCenters();

                    using (Brush handleBrush = new SolidBrush(Color.Yellow))
                    using (Pen handlePen = new Pen(Color.Black, 1))
                    {
                        foreach (var handle in handles)
                        {
                            float handleSize = HANDLE_SIZE;
                            g.FillRectangle(handleBrush,
                                handle.Value.X - handleSize / 2,
                                handle.Value.Y - handleSize / 2,
                                handleSize, handleSize);

                            g.DrawRectangle(handlePen,
                                handle.Value.X - handleSize / 2,
                                handle.Value.Y - handleSize / 2,
                                handleSize, handleSize);
                        }
                    }
                }
            }
            finally
            {
                g.Restore(state);
            }
        }

        private void DrawHandles(Graphics g)
        {
            var handles = GetHandleCenters();

            using (Brush fillBrush = new SolidBrush(Color.Yellow))
            using (Pen borderPen = new Pen(Color.Black, 1))
            {
                foreach (var handle in handles)
                {
                    RectangleF handleRect = new RectangleF(
                        handle.Value.X - HANDLE_SIZE / 2,
                        handle.Value.Y - HANDLE_SIZE / 2,
                        HANDLE_SIZE, HANDLE_SIZE);

                    g.FillRectangle(fillBrush, handleRect);
                    g.DrawRectangle(borderPen, handleRect.X, handleRect.Y, handleRect.Width, handleRect.Height);
                }
            }
        }

        public enum HandleType { StartAngle, EndAngle, TopLeft, BottomRight }
        public Dictionary<HandleType, PointF> GetHandles()
        {
            return new Dictionary<HandleType, PointF>
            {
                [HandleType.StartAngle] = GetArcPoint(StartAngle),
                [HandleType.EndAngle] = GetArcPoint(StartAngle + SweepAngle),
                [HandleType.TopLeft] = new PointF(TopLeftX, TopLeftY),
                [HandleType.BottomRight] = new PointF(TopLeftX + Width, TopLeftY + Height)
            };
        }

        public Dictionary<HandleType, PointF> GetHandleCenters()
        {
            Dictionary<HandleType, PointF> handles = new Dictionary<HandleType, PointF>();

            // 获取边界矩形
            RectangleF bounds = new RectangleF(TopLeftX, TopLeftY, Width, Height);

            // 计算边界把手
            handles[HandleType.TopLeft] = new PointF(bounds.Left, bounds.Top);
            handles[HandleType.BottomRight] = new PointF(bounds.Right, bounds.Bottom);

            // 使用已计算好的控制点作为角度控制点
            handles[HandleType.StartAngle] = StartPoint;
            handles[HandleType.EndAngle] = EndPoint;

            return handles;
        }

        private PointF GetArcPoint(float angle)
        {
            // 安全检查：确保宽高为正数
            if (Width <= 0 || Height <= 0)
            {
                // 返回中心点作为默认值
                return new PointF(TopLeftX, TopLeftY);
            }

            float centerX = TopLeftX + Width / 2;
            float centerY = TopLeftY + Height / 2;
            float radiusX = Width / 2;
            float radiusY = Height / 2;

            float angleRad = angle * (float)Math.PI / 180;
            PointF arcPoint = new PointF(
                centerX + radiusX * (float)Math.Cos(angleRad),
                centerY + radiusY * (float)Math.Sin(angleRad)
            );

            // 如果有旋转，应用旋转变换
            if (Rotation != 0 && _rotationMatrix != null)
            {
                PointF[] points = new PointF[] { arcPoint };
                try
                {
                    // 使用旋转矩阵变换点
                    RotationMatrix.TransformPoints(points);
                    return points[0];
                }
                catch
                {
                    // 如果变换失败，返回原始点
                    return arcPoint;
                }
            }

            return arcPoint;
        }
        #endregion

        public override bool Contains(Point p)
        {
            // 实现点击检测
            if (Width <= 0 || Height <= 0) return false;

            using (GraphicsPath path = new GraphicsPath())
            {
                float centerX = TopLeftX + Width / 2;
                float centerY = TopLeftY + Height / 2;

                // 创建圆弧路径
                path.AddArc(TopLeftX, TopLeftY, Width, Height, StartAngle, SweepAngle);

                // 如果圆弧不是整圆，添加从起点到终点的线段
                if (Math.Abs(SweepAngle) < 360)
                {
                    // 添加从起点到中心的线段
                    path.AddLine(StartPoint, new PointF(centerX, centerY));

                    // 添加从中心到终点的线段
                    path.AddLine(new PointF(centerX, centerY), EndPoint);
                }

                // 应用旋转变换
                path.Transform(RotationMatrix);

                // 使用较宽的画笔进行点击检测
                using (Pen testPen = new Pen(Color.Black, 5))
                {
                    return path.IsOutlineVisible(p, testPen) || path.IsVisible(p);
                }
            }
        }

        // 移动方法，带图像坐标更新
        public override void Move(float dx, float dy, Func<PointF, PointF> overlayToImageTransform)
        {
            // 移动圆弧的基本参数
            TopLeftX += dx;
            TopLeftY += dy;

            // 移动旋转中心点
            _rotationCenter = new PointF(_rotationCenter.X + dx, _rotationCenter.Y + dy);

            // 标记矩阵为脏
            _matrixDirty = true;

            // 更新控制点位置
            UpdateArcPoints();

            // 如果有坐标转换函数，更新图像坐标
            if (overlayToImageTransform != null)
            {
                UpdateImageCoordinates(overlayToImageTransform);
            }
        }

        public void Dispose()
        {
            _rotationMatrix?.Dispose();
            Pen?.Dispose();
        }
    }
}
